package com.itheima.filter;

import com.itheima.common.util.JwtUtil;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.Charset;

/**
 * @Author：shenkunlin
 * @date： 2021/8/20 9:06
 * @Description：
 *  1:全局过滤器 实现接口GlobalFilter接口，排序实现接口Ordered
 *  2:鉴权
 *      1)/account/login 登录地址：放行
 *      2)其他地址，如果没有token，拦截
 *      3)获取当前请求数据中头部中token
 *      4)如果token不为空，则鉴定当前token
 *      5)token没有问题，放行
 *        token有问题，则拦截
 *
 *
 ***/
@Configuration
public class AuthorizeFilter implements GlobalFilter, Ordered {

    /**
     * 拦截
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //Request->客户端提交的数据封装
        ServerHttpRequest request = exchange.getRequest();
        //Response->响应数据的封装
        ServerHttpResponse response = exchange.getResponse();

        //1)/account/login 登录地址：放行
        String path = request.getURI().getPath();
        if(path.contains("/login")){
            return chain.filter(exchange);
        }
        //2)获取当前请求数据中头部中token
        String token = request.getHeaders().getFirst("token");

        //3)其他地址，如果没有token，拦截
        //4)如果token不为空，则鉴定当前token
        //  token有问题，则拦截
        if(StringUtils.isEmpty(token) || !JwtUtil.verifyToken(token)){
            //401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            return response.writeWith(Flux.just(response.bufferFactory().wrap("请您先登录！".getBytes(Charset.forName("UTF-8")))));
        }
        //5)token没有问题，放行
        //  token有问题，则拦截
        return chain.filter(exchange);
    }

    /**
     * 拦截器排序
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
